package com.google.wave.extensions.code;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.wave.api.TextView;
import com.google.wave.api.Range;
import com.google.wave.api.Annotation;

/**
 * {@code WaveUtils} contains a few useful methods that probably
 * should have been part of the Wave API but are not (yet).
 * 
 * @author schwardo@google.com (Don Schwarz)
 */
public class WaveUtils {
    /**
     * Hacky way to delete all annotations of the given name in the given range.  I've filed a feature
     * reques to have this added to the Wave API.
     */
    public static void deleteAnnotations(TextView document, Range range, String name) {
	// Save the old annotations for that name.
	Map<Range, String> ranges = new HashMap<Range, String>();
	for (Annotation ann : document.getAnnotations(name)) {
	    // Ignore the ones we want to remove.
	    if (ann.getRange().getStart() > range.getStart() || ann.getRange().getEnd() > range.getEnd()) {
		ranges.put(ann.getRange(), ann.getValue());
	    }
	}

	// Delete them all.
	document.deleteAnnotations(name);

	// Then add back in the ones we didn't want to delete.
	for (Map.Entry<Range, String> entry : ranges.entrySet()) {
	    document.setAnnotation(entry.getKey(), name, entry.getValue());
	}
    }

    /**
     * Returns all annotations that occur within the specified range in
     * {@code document}.  Note that this differs from {@link
     * TextView.getAnnotations(Range)}, which returns the annotations
     * whose ranges contain {@code range}.
     */
    public static List<Annotation> getAnnotationsWithin(TextView document, Range range) {
	List result = new ArrayList<Annotation>();
	for (Annotation annotation : document.getAnnotations()) {
	    Range annotationRange = annotation.getRange();
	    if (annotationRange.getStart() >= range.getStart() &&
		annotationRange.getEnd() <= range.getEnd()) {
		result.add(annotation);
	    }
	}
	return result;
    }
}
